// +FHDR------------------------------------------------------------
//                 Copyright (c) 2022 .
//                       ALL RIGHTS RESERVED
// -----------------------------------------------------------------
// Filename      : base_test.sv
// Author        : 
// Created On    : 
// Last Modified : 2022-11-30 13:22 by gaojiaming
// -----------------------------------------------------------------
// Description:
//
//
// -FHDR------------------------------------------------------------

`ifndef BASE_TEST_SV
`define BASE_TEST_SV

class base_test extends uvm_test;

    ral_block_PPU_REG_ppu_reg ral_model;
    ppu_env env;

    cpu_agent     cpu_mst;
    cpu_adapter   adapter;
    uvm_status_e  status;
	
	extern function new(string name = "base_test", uvm_component parent=null);
	extern virtual function void build_phase(uvm_phase phase);
	extern virtual function void connect_phase(uvm_phase phase);
    extern virtual task configure_phase(uvm_phase phase);
    extern virtual task main_phase(uvm_phase phase);
    extern virtual task watchdog(uvm_phase phase);

	`uvm_component_utils(base_test)
endclass: base_test

function base_test::new(string name = "base_test", uvm_component parent=null);
	super.new(name, parent);
endfunction: new

function void base_test::build_phase(uvm_phase phase);
	super.build_phase(phase);
    set_report_max_quit_count(5);

    cpu_mst = cpu_agent::type_id::create("cpu_mst", this);
    cpu_mst.is_active = UVM_ACTIVE;
    adapter = cpu_adapter::type_id::create("adapter", this);

    if(!uvm_config_db #(ral_block_PPU_REG_ppu_reg)::get(this, "", "ral_model", ral_model)) begin
        uvm_reg::include_coverage("*",UVM_CVR_ALL);
        ral_model = ral_block_PPU_REG_ppu_reg::type_id::create("ral_model", this);
        ral_model.build();
        ral_model.lock_model();
        ral_model.reset();
        ral_model.set_coverage(UVM_CVR_ALL);
    end
    adapter = cpu_adapter::type_id::create("adapter", this);
    env = ppu_env::type_id::create("env", this);
    uvm_config_db #(ral_block_PPU_REG_ppu_reg)::set(this, "env.rm", "ral_model", ral_model);
endfunction: build_phase

function void base_test::connect_phase(uvm_phase phase);
	super.connect_phase(phase);
    ral_model.default_map.set_sequencer(cpu_mst.sqr, adapter);
    ral_model.default_map.set_auto_predict(1);
endfunction: connect_phase

task base_test::configure_phase(uvm_phase phase);
    super.configure_phase(phase);
endtask

task base_test::main_phase(uvm_phase phase);
    super.main_phase(phase);
    phase.raise_objection(this);
    this.watchdog(phase);
    phase.drop_objection(this);
endtask

task base_test::watchdog(uvm_phase phase);
	#1000;
	while(1)begin
		bit vr_reached;
		fork: timeout
			begin //normal finish
				phase.phase_done.wait_for_total_count(null, 1);
				vr_reached = 1;
			end
			begin //timeout
				#100000;
				`uvm_fatal("base_test", $psprintf("watchdog timeout(%s_phase)::\n %s", phase.get_name(), phase.phase_done.convert2string()))
			end
            #1000 @(env.scb.feed_watchdog);
            #1000 @(env.rm.feed_watchdog);
		join_any
		disable timeout;
	
		#100;
		if(vr_reached && phase.phase_done.get_objection_total() == 1)begin
			`uvm_info("watchdog", "watchdog timeout normal reached", UVM_LOW)
			break;
		end
	end
	`uvm_info("base_test", "watchdog(): Finished!", UVM_LOW)
endtask

`endif
